(function($) {
    $.fn.ThreePlanet = function(options) {
        var _this = this;
        var _w;
        var _h;

        var _halfX;
        var _halfY;

        var _scene,
            _camera,
            _renderer,
            _controls,
            _root,
            _raycaster = new THREE.Raycaster();

        var isMove = false;
        var _nextList = [];

        var _plantNameList = [];
        var selected = null;
        var _data = {
            aixin: {
                name: 'aixin',
                info: [
                    {
                        url: 'images/models/sphere.obj',
                        position: {
                            x: 24,
                            y: 20,
                            z: 133
                        },
                        rotation: {
                            x: 0,
                            y: 0,
                            z: 0
                        },
                        scale: {
                            x: 1,
                            y: 1,
                            z: 1
                        },
                        endPosition: {
                            x: 42,
                            y: 36,
                            z: 242,
                            x1: -0.5,
                            y1: -0.23,
                            z1: -0.12
                        }
                    },
                    {
                        url: 'images/models/aixin.obj',
                        position: {
                            x: 24,
                            y: 20,
                            z: 133
                        },
                        rotation: {
                            x: 0,
                            y: 0,
                            z: 0
                        },
                        scale: {
                            x: 1,
                            y: 1,
                            z: 1
                        },
                        endPosition: {
                            x: 42,
                            y: 36,
                            z: 242,
                            x1: -0.5,
                            y1: -0.23,
                            z1: -0.12
                        }
                    }
                ]
            },
            jinqian: {
                name: 'jinqian',
                info: [
                    {
                        url: 'images/models/sphere.obj',
                        position: {
                            x: -4,
                            y: 10,
                            z: 52
                        },
                        rotation: {
                            x: 0,
                            y: 0,
                            z: 0
                        },
                        scale: {
                            x: 1,
                            y: 1,
                            z: 1
                        },
                        endPosition: {
                            x: -14,
                            y: 36,
                            z: 162,
                            x1: -0.5,
                            y1: -0.23,
                            z1: -0.12
                        }
                    },
                    {
                        url: 'images/models/jinqian.obj',
                        position: {
                            x: -4,
                            y: 10,
                            z: 52
                        },
                        rotation: {
                            x: 0,
                            y: 0,
                            z: 0
                        },
                        scale: {
                            x: 1,
                            y: 1,
                            z: 1
                        },
                        endPosition: {
                            x: -14,
                            y: 36,
                            z: 162,
                            x1: -0.5,
                            y1: -0.23,
                            z1: -0.12
                        }
                    }
                ]
            },
            dengpao: {
                name: 'dengpao',
                info: [
                    {
                        url: 'images/models/sphere.obj',
                        position: {
                            x: 26,
                            y: -14,
                            z: -56
                        },
                        rotation: {
                            x: 0,
                            y: 0,
                            z: 0
                        },
                        scale: {
                            x: 0.8,
                            y: 0.8,
                            z: 0.8
                        },
                        endPosition: {
                            x: -14,
                            y: 6,
                            z: 30,
                            x1: -0.5,
                            y1: -0.23,
                            z1: -0.12
                        }
                    },
                    {
                        url: 'images/models/dengpao.obj',
                        position: {
                            x: 26,
                            y: -14,
                            z: -56
                        },
                        rotation: {
                            x: 0,
                            y: 0,
                            z: 0
                        },
                        scale: {
                            x: 0.8,
                            y: 0.8,
                            z: 0.8
                        },
                        endPosition: {
                            x: -14,
                            y: 6,
                            z: 30,
                            x1: -0.5,
                            y1: -0.23,
                            z1: -0.12
                        }
                    }
                ]
            },
            chilun: {
                name: 'chilun',
                info: [
                    {
                        url: 'images/models/sphere.obj',
                        position: {
                            x: 84,
                            y: 10,
                            z: 52
                        },
                        rotation: {
                            x: 0,
                            y: 0,
                            z: 0
                        },
                        scale: {
                            x: 1,
                            y: 1,
                            z: 1
                        },
                        endPosition: {
                            x: 214,
                            y: 36,
                            z: 112,
                            x1: -0.5,
                            y1: -0.23,
                            z1: -0.12
                        }
                    },
                    {
                        url: 'images/models/chilun.obj',
                        position: {
                            x: 84,
                            y: 10,
                            z: 52
                        },
                        rotation: {
                            x: 0,
                            y: 0,
                            z: 0
                        },
                        scale: {
                            x: 1,
                            y: 1,
                            z: 1
                        },
                        endPosition: {
                            x: 214,
                            y: 36,
                            z: 112,
                            x1: -0.5,
                            y1: -0.23,
                            z1: -0.12
                        }
                    }
                ]
            }
        };

        //当前选中索引
        var _selectedIndex = -1;

        //点击坐标
        var _mouse = new THREE.Vector2();
        //旧的坐标
        var _oldPos = new THREE.Vector3();

        //lookat
        var _initLookat;
        var _changeVar;
        var _tween;

        var _isTouch = false;
        var _targetRotationX = 0;
        var _targetRotationY = 0;
        var _targetRotationOn_mouseDownX = 0;
        var _targetRotationOn_mouseDownY = 0;
        var _mouseXOn_mouseDownX = 0;
        var _mouseXOn_mouseDownY = 0;

        var _startAnim = true;

        var _setting = {
            onPlantSelect: function() {},
            onInit: function() {}
        };
        $.extend(true, _setting, options);

        //============ init ================
        _init();
        //============= Private ===============
        /**
         * 初始化
         * */
        function _init() {
            _initTween();
            _initData();
            _initRenderer();
            _initCamera();
            _initScene();
            _initControls();
            _initLight();
            _initBg();
            _addEvent();
            setTimeout(function() {
                _setting.onInit();
                _animation();
            }, 500);
        }
        function _initTween() {
            _initLookat = new THREE.Vector3(0, 0, 0);
            _changeVar = {
                x: 0,
                y: 0,
                z: 0,
                scale: 1,
                x1: _initLookat.x,
                y1: _initLookat.y,
                z1: _initLookat.z
            };
            _tween = new TWEEN.Tween(_changeVar);
            _tween.onComplete(function() {
                // 在tween动画全部结束后执行。
                if (_startAnim) {
                    _startAnim = false;
                } else {
                    if (selected == null && !_controls.enabled) {
                        _controls.enabled = true;
                        _next();
                    } else {
                        _setting.onPlantSelect(_selectedIndex);
                    }
                }
            });
        }
        function _initPlanet(params) {
            _drawPlanet();
        }
        /**
         * 初始化数据
         * */
        function _initData() {
            _w = $(this).width();
            _h = $(this).height();
            _halfX = _w * 0.5;
            _halfY = _h * 0.5;
            for (var b in _data) {
                _plantNameList.push(_data[b].name);
            }
        }
        /**
         * 初始化场景
         * */
        function _initScene() {
            var path = 'images/skybox/';
            var format = '.jpg';
            var urls = [
                path + 'posy' + format,
                path + 'negy' + format,
                path + 'posz' + format,
                path + 'negz' + format,
                path + 'posx' + format,
                path + 'negx' + format
            ];
            var reflectionCube = new THREE.CubeTextureLoader().load(urls);
            reflectionCube.format = THREE.RGBFormat;
            _scene = new THREE.Scene();
            // _scene.background = new THREE.Color(0x000000);
            _scene.background = reflectionCube;
            _root = new THREE.Group();
            _root.name = 'system';
            _scene.add(_root);
        }
        /**
         * 初始化相机
         * */
        function _initCamera() {
            _camera = new THREE.PerspectiveCamera(45, _w / _h, 0.1, 15000);
            _camera.position.set(0, 0, 500);
        }
        /**
         * 初始化渲染器
         * */
        function _initRenderer() {
            _renderer = new THREE.WebGLRenderer({
                antialias: true, //抗锯齿
                alpha: true
            });
            _renderer.setPixelRatio(window.devicePixelRatio);
            _renderer.setSize(_w, _h);
            _renderer.setClearColor(0xcce0ff, 0);
            $(_this).append(_renderer.domElement);
        }
        /**
         * 初始化相机控制
         * autoRotate(Boolean)
         * autoRotateSpeed(Default is 2.0)
         * dampingFactor(阻尼系数)
         */
        function _initControls() {
            _controls = new THREE.OrbitControls(_camera, _renderer.domElement);
            _controls.enableDamping = true;
            _controls.dampingFactor = 0.25;
            _controls.enableZoom = false;
            _controls.minDistance = 0.1;
            _controls.maxDistance = 3700;
            _controls.rotateSpeed = 0.1;
            _controls.autoRotate = true;
            _controls.autoRotateSpeed = 0.1;
        }
        /**
         * 初始化灯光
         */
        function _initLight() {
            //环境光
            var ambLight = new THREE.AmbientLight(0x0184c2, 1);
            ambLight.intensity = 1;
            _scene.add(ambLight);
        }
        /**
         * 初始化天空盒子
         */
        function _initBg() {
            var imagePrefix = 'images/skybox/';
            var directions = [
                'skybox1x',
                'skybox1x',
                'skybox2x',
                'skybox2x',
                'skybox1x',
                'skybox1x'
            ];
            var imageSuffix = '.jpg';
            var materials = [];
            $.each(directions, function(index, obj) {
                var texture = new THREE.Texture();
                var loader = new THREE.ImageLoader();
                loader.load(imagePrefix + obj + imageSuffix, function(image) {
                    texture.image = image;
                    texture.needsUpdate = true;
                });
                materials[index] = new THREE.MeshBasicMaterial({
                    map: texture,
                    side: THREE.BackSide,
                    overdraw: 0.5
                });
            });
            var skyMesh = new THREE.Mesh(
                new THREE.BoxGeometry(1000, 1000, 1000),
                new THREE.MeshFaceMaterial(materials)
            );
            skyMesh.position.set(0, 0, 0);
            skyMesh.rotation.set(0, 0, 0);
            skyMesh.scale.x = -1;
            _scene.add(skyMesh);
        }
        /**
         * 画星球
         */
        function _drawPlanet() {
            for (var b in _data) {
                _data[b].info.forEach(element => {
                    _creatPlant({
                        name: _data[b].name,
                        url: element.url,
                        scale: element.scale,
                        position: element.position,
                        rotation: element.rotation,
                        otherValue: {
                            startPosition: element.position,
                            endPosition: element.endPosition
                        },
                        scene: _root
                    });
                });
            }
        }

        function _creatPlant(b) {
            var manager = new THREE.LoadingManager();
            manager.onProgress = function(item, loaded, total) {
                // console.log(item, loaded, total);
            };
            var onProgress = function(xhr) {
                if (xhr.lengthComputable) {
                    var percentComplete = xhr.loaded / xhr.total * 100;
                    // console.log(
                    //     Math.round(percentComplete, 2) + '% downloaded'
                    // );
                }
            };
            var onError = function(xhr) {
                console.log(xhr);
            };
            // var textureLoader = new THREE.TextureLoader(manager);
            // var texture = textureLoader.load(textureModel);
            // 导入模型
            // var obj = new THREE.Object3D();
            // obj.name = b.name;
            // // obj.position.copy(point.position.clone());
            // obj.position.set(b.position.x, b.position.y, b.position.z);
            // obj.scale.set(b.scale.x, b.scale.y, b.scale.z);
            // obj.rotation.set(b.rotation.x, b.rotation.y, b.rotation.z);
            var loader = new THREE.OBJLoader(manager);
            loader.load(
                b.url,
                function(object) {
                    object.traverse(function(e) {
                        e.name = b.name;
                        e.position.set(
                            b.position.x,
                            b.position.y,
                            b.position.z
                        );
                        e.scale.set(b.scale.x, b.scale.y, b.scale.z);
                        e.rotation.set(
                            b.rotation.x,
                            b.rotation.y,
                            b.rotation.z
                        );
                        e.otherValue = {};
                        for (var g in b.otherValue) {
                            e.otherValue[g] = b.otherValue[g];
                        }
                        b.scene.add(e);
                    });
                },
                onProgress,
                onError
            );
        }

        function _next(flag) {
            if (_nextList.length > 0) {
                _selectedIndex = _nextList.shift();

                //关闭拖动
                if (_nextList.length == 0) {
                    _controls.enabled = false;
                }

                //赋值
                selected = flag;
                console.log(_plantNameList);
                console.log(_selectedIndex);
                console.log(selected);

                var _max = selected.otherValue.endPosition;
                console.log(_max);

                _changeVar.x = _camera.position.x;
                _changeVar.y = _camera.position.y;
                _changeVar.z = _camera.position.z;

                //记录一下当前摄像机的坐标 方便后面还原
                if (flag) _oldPos = _camera.position.clone();

                _tween.to(_max, 1000);
                _tween.start();
            }
        }

        function _cameraRender() {
            _camera.position.x = _changeVar.x;
            _camera.position.y = _changeVar.y;
            _camera.position.z = _changeVar.z;

            _initLookat.x = _changeVar.x1;
            _initLookat.y = _changeVar.y1 + _root.rotation.y;
            _initLookat.z = _changeVar.z1;
            _camera.lookAt(_initLookat);
            TWEEN.update();
        }
        /**
         * 初始化动画
         */
        function _animation() {
            requestAnimationFrame(_animation);
            _render();
            _renderer.render(_scene, _camera);
        }
        function _render() {
            _root.children.forEach(element => {
                element.rotation.y += 0.005;
                // element.rotation.z += 0.005;
            });
            if (_startAnim) {
                _cameraRender();
            } else {
                if (_controls && _controls.enabled) {
                    _controls.update();
                } else {
                    _cameraRender();
                }
            }
        }

        //============= Event ===============
        /**
         * 增加事件监听
         */
        function _addEvent() {
            $(this).on('touchstart', _touchStartHandler);
            $(this).on('touchmove', _touchMoveHandler);
            $(this).on('touchend', _touchEndHandler);
        }
        function _touchStartHandler(e) {
            e.preventDefault();
            isMove = false;
            if (event.touches.length == 1) {
                _isTouch = true;
                _mouseXOn_mouseDownX = event.touches[0].pageX - _halfX;
                _mouseXOn_mouseDownY = event.touches[0].pageY - _halfY;
                _targetRotationOn_mouseDownX = _targetRotationX;
                _targetRotationOn_mouseDownY = _targetRotationY;
            }
        }
        function _touchMoveHandler(e) {
            e.preventDefault();
            isMove = true;
            if (!_controls.enabled && selected) {
                if (event.touches.length == 1) {
                    _mouse.x = event.touches[0].pageX - _halfX;
                    _mouse.y = event.touches[0].pageY - _halfY;
                    _targetRotationX =
                        _targetRotationOn_mouseDownX +
                        (_mouse.x - _mouseXOn_mouseDownX) * 0.01;
                    _targetRotationY =
                        _targetRotationOn_mouseDownY +
                        (_mouse.y - _mouseXOn_mouseDownY) * 0.01;
                }
            }
        }
        function _touchEndHandler(e) {
            _isTouch = false;
            if (_controls.enabled && !isMove) {
                _mouse.x = event.changedTouches[0].clientX / _w * 2 - 1;
                _mouse.y = -(event.changedTouches[0].clientY / _h) * 2 + 1;
                _mouse.search = _root ? _root : _scene;

                _raycaster.setFromCamera(_mouse, _camera);
                var intersects = _raycaster.intersectObjects(
                    _mouse.search.children
                );
                if (intersects.length > 0) {
                    // for (var i = 0; i < intersects.length; i++) {
                    //     // intersects[i].object.material.color.set(0x0184c2);
                    //     var g = intersects[i].object;
                    //     for (var j in _data) {
                    //         var index = _data[j].name.indexOf(g.name);
                    //         if ((g.name = _data[j].name)) {
                    //             _nextList.push(index);
                    //             _next(true);
                    //             break;
                    //         }
                    //     }
                    // }
                    var obj = intersects[0].object;
                    console.log(obj)
                    var index = _plantNameList.indexOf(obj.name);
                    if (index != -1) {
                        _nextList.push(index);
                        _next(obj);
                    }
                }
            }
        }

        //============= Public ===============
        _this.initPlanet = function() {
            _initPlanet();
        };
        //当前显示索引
        _this.currentIndex = function() {
            return _selectedIndex;
        };
        _this.goto = function(index, callback) {
            if (_selectedIndex == index) return;
            callback = callback || function() {};
            _nextList.push(index);
            _next(false);
        };
        _this.show = function() {
            _camera.position.set(0, 0, 0);
            _changeVar.x = _camera.position.x;
            _changeVar.y = _camera.position.y;
            _changeVar.z = _camera.position.z;
            _tween.to(
                {
                    x: 180,
                    y: 90,
                    z: 299
                },
                5000
            );
            _tween.start();
        };
        //回退
        _this.back = function() {
            if (selected) {
                selected = null;
                //还原数据
                _tween.to(
                    {
                        x: _oldPos.x,
                        y: _oldPos.y,
                        z: _oldPos.z,
                        x1: 0,
                        y1: 0,
                        z1: 0,
                        scale: 1
                    },
                    1000
                );
                _tween.start();
            }
        };

        return _this;
    };
})(jQuery);
